using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

using AlfarEngine;
using AlfarEngine.Components;

using EngineTest.GameObjects;

namespace EngineTest
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        GameObject lObjLamp;
        GameObject lObjCam;

        float mLastTime = 0;
        Vector2 mTargetPos = new Vector2(-100, -200);
        Vector2 mBasePos;

        Vector2 mBasePosCam = Vector2.Zero;
        Vector2 mTargetPosCam = new Vector2(300, 0);

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            IsFixedTimeStep = false;
            graphics.SynchronizeWithVerticalRetrace = true;
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            Engine.Initialize(this, graphics);
            Engine.ambientLight = 0.5f;
            Engine.cursor = true;
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            
            /*Collider lCollider;
            
            GameObject lObj = new GameObject();
            AlfarEngine.Components.AnimatedSprite lSpr = lObj.AddComponent<AlfarEngine.Components.AnimatedSprite>();
            lSpr.setTexture("textures/catWalk");
            lSpr.sourceRect = new Rectangle(0, 0, 128, 128);
            lSpr.AddAnimation("walk", 2.0f, 13, 0);
            lSpr.Play("walk");
            lCollider = lObj.AddComponent<Collider>();
            lCollider.bounds = new Rectangle(0, 0, 100, 100);
            

            GameObject lObj3 = new GameObject();
            lSpr = lObj3.AddComponent<AlfarEngine.Components.AnimatedSprite>();
            lSpr.setTexture("textures/catWalk");
            lSpr.sourceRect = new Rectangle(0, 0, 128, 128);
            lSpr.AddAnimation("walk", 0.7f, 13, 0);
            lSpr.Play("walk");
            lObj3.position = new Vector2(-200, 100);
            lCollider = lObj3.AddComponent<Collider>();
            lCollider.bounds = new Rectangle(0, 0, 100, 100);*/

            Player lPlayer = new Player();
            lPlayer.position = new Vector2(-200, -90);

            lObjCam = new GameObject("Camera");
            lObjCam.AddComponent<AlfarEngine.Components.Camera>();

            //------Ground

            GameObject lGround;

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    lGround = new GameObject();
                    lGround.position = new Vector2(i * 64 - Engine.resolution.X / 2.0f, j * 64 - Engine.resolution.Y / 2.0f);
                    AlfarEngine.Components.Sprite lSprGrd = lGround.AddComponent<AlfarEngine.Components.Sprite>();

                    lSprGrd.setTexture("textures/tile");
                    Engine.root[2].AddObject(lGround);
                }
            }

            //------------

            //Engine.root[1].AddObject(lObj);
            //Engine.root[1].AddObject(lObj3);

            BinaryReader lRd = new BinaryReader(File.Open("save", FileMode.Open));
            Engine.root[1].Deserialize(lRd);
            lRd.Close();

            Engine.root[0].AddObject(lObjCam);

            Engine.root[1].BuildBoundingRect();
            Engine.root[2].BuildBoundingRect();

            /*BinaryWriter lWrt = new BinaryWriter(File.Open("save", FileMode.Create));

            Engine.root[1].Serialize(lWrt);

            lWrt.Close();*/
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            /*mLastTime += (float)gameTime.ElapsedGameTime.TotalSeconds;

            if(mLastTime > 3.0f)
            {
                mLastTime = 0;

                if(mBasePos == new Vector2(-120, -200))
                {
                    mBasePos = new Vector2(-120, 70);
                    mTargetPos = new Vector2(-120, -200);
                }
                else
                {
                    mTargetPos = new Vector2(-120, 70);
                    mBasePos = new Vector2(-120, -200);
                }

                if (mBasePosCam == Vector2.Zero)
                {
                    mBasePosCam = mTargetPosCam;
                    mTargetPosCam = Vector2.Zero;
                }
                else
                {
                    mTargetPosCam = mBasePosCam;
                    mBasePosCam = Vector2.Zero;
                }
            }*/

            /*lObjLamp.GetComponent<AlfarEngine.Components.SpotLight>().direction = Vector2.Transform(lObjLamp.GetComponent<AlfarEngine.Components.SpotLight>().direction,
                                                                                                    Matrix.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.ToRadians(120.0f * (float)gameTime.ElapsedGameTime.TotalSeconds)));
            */
            //lObjLamp.position = Vector2.Lerp(mBasePos, mTargetPos, mLastTime / 3.0f);
            //lObjCam.position = Vector2.Lerp(mBasePosCam, mTargetPosCam, mLastTime / 3.0f);

            Engine.Update(gameTime);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            Engine.Draw(gameTime);

            base.Draw(gameTime);
        }
    }
}
